<template>
  <div class="thinking-process-container">
    <svg ref="svgElement" width="100%" height="600px" class="thinking-svg"></svg>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import * as d3 from 'd3';

const svgElement = ref(null);

class ThinkingProcessVisualizer {
  constructor(svgElement) {
    this.svg = d3.select(svgElement);
    this.width = svgElement.clientWidth;
    this.height = svgElement.clientHeight;
    this.duration = 750;
    this.treeData = {
      id: "root",
      name: "核心问题",
      children: []
    };
    
    this.init();
  }
  
  init() {
    // 清空并设置SVG
    this.svg.selectAll("*").remove();
    
    // 创建缩放容器
    this.g = this.svg.append("g");
    
    // 设置缩放行为
    this.zoom = d3.zoom()
      .scaleExtent([0.1, 5])
      .on("zoom", (event) => {
        this.g.attr("transform", event.transform);
      });
    
    this.svg.call(this.zoom);
    
    // 创建树布局
    this.tree = d3.tree()
      .size([this.height, this.width - 200]);
    
    // 初始化树
    this.root = d3.hierarchy(this.treeData);
    this.root.x0 = this.height / 2;
    this.root.y0 = this.width / 2;
    this.update(this.root);
  }
  
  update(source) {
    // 计算新树布局
    this.tree(this.root);
    
    // 获取节点和连接
    const nodes = this.root.descendants();
    // const links = this.root.links();
    
    // 设置节点位置
    nodes.forEach(d => {
      d.y = this.height / 2;
      d.x = d.depth * 200;
    });
    
    // // 更新连接线
    // const link = this.g.selectAll(".link")
    //   .data(links, d => d.target.id);
    
    // // 添加新连接线
    // const linkEnter = link.enter().append("path")
    //   .attr("class", "link")
    //   .attr("d", d3.linkHorizontal()
    //     .x(d => d.y + 50)
    //     .y(d => d.x + 20))
    //   .attr("fill", "none")
    //   .attr("stroke", "#555")
    //   .attr("stroke-width", 2);
    
    // // 更新现有连接线
    // link.merge(linkEnter)
    //   .transition()
    //   .duration(this.duration)
    //   .attr("d", d3.linkHorizontal()
    //     .x(d => d.y + 50)
    //     .y(d => d.x + 20));
    
    // // 移除多余连接线
    // link.exit().remove();
    
    // 更新节点
    const node = this.g.selectAll(".node")
      .data(nodes, d => d.id);
    
    // 添加新节点
    const nodeEnter = node.enter().append("g")
      .attr("class", "node")
      .attr("transform", () => `translate(${source.y0},${source.x0})`);
    
    // 添加节点长方体
    nodeEnter.append("rect")
      .attr("width", 200)
      .attr("height", 100)
      .attr("fill", "blue")
      .attr("stroke", "#fff")
      .attr("stroke-width", 2.5)
      .attr("rx", 10)
      .attr("ry", 10);
    // 添加节点文本
    // 添加节点文本
    nodeEnter.append("text")
      .attr("dy", "1.2em")
      .attr("x", 100) // 水平居中
      .attr("y", 50) // 垂直居中
      .attr("text-anchor", "middle")
      .text(d => d.data.name)
      .attr("fill", "#fff")
      .attr("font-size", "25px");
    
    // 更新节点位置
    const nodeUpdate = node.merge(nodeEnter)
      .transition()
      .duration(this.duration)
      .attr("transform", d => `translate(${d.y},${d.x})`);
    
    // 更新节点样式
    nodeUpdate.select("rect")
  .attr("width", 200)
  .attr("height", 100)
  .attr("fill", "#79bcff")
  .attr("stroke", "#fff")
  .attr("stroke-width", 2.5)
  .attr("rx", 10)
  .attr("ry", 10);
    // 更新文本位置
  nodeUpdate.select("text")
    .attr("dy", "1.2em")
    .attr("x", 100) // 水平居中
    .attr("y", 50) // 垂直居中
    .attr("text-anchor", "middle");
    // 移除多余节点
    node.exit()
      .transition()
      .duration(this.duration)
      .attr("transform", () => `translate(${source.y},${source.x})`)
      .remove();
    
    // 存储旧位置
    nodes.forEach(d => {
      d.x0 = d.x;
      d.y0 = d.y;
    });
  }
  getHeightForNode(node) {
    // 根据节点的深度或其他条件调整节点的垂直位置
    return this.width / 2;
  }
  
  addNode(parentId, newNodeData) {
    // 查找父节点
    const parentD3 = this.findD3NodeById(parentId);
    if (!parentD3) return;
    
    // 创建新节点
    const newD3Node = d3.hierarchy({
      id: newNodeData.id,
      name: newNodeData.name,
      children: [],
      data: newNodeData
    });
    
    // 添加到父节点
    if (!parentD3.children) parentD3.children = [];
    parentD3.children.push(newD3Node);
    newD3Node.depth = parentD3.depth + 1;
    newD3Node.parent = parentD3;
    
    // 更新树
    this.update(parentD3);
  }
  
  findD3NodeById(id, node = this.root) {
    if (node.data.id === id) return node;
    if (node.children) {
        for (const child of node.children) {
            const found = this.findD3NodeById(id, child);
            if (found) return found;
        }
    }
    return null;
  }
  startBlink(nodeId) {
    const nodeCircle = this.svg.select(`#node-${nodeId} circle`);
    nodeCircle.classed('blink', true);
  }
}

const thinkingProcessVisualizer = ref(null);

onMounted(() => {
  thinkingProcessVisualizer.value = new ThinkingProcessVisualizer(svgElement.value);
  
  // 示例：动态添加节点
  setTimeout(() => {
    thinkingProcessVisualizer.value.addNode("root", { id: "node1", name: "问题分析" });
  }, 4000);
  setTimeout(() => {
    thinkingProcessVisualizer.value.addNode("node1", { id: "node3", name: "解决方案" });
  }, 8000);
  setTimeout(() => {
    thinkingProcessVisualizer.value.addNode("node3", { id: "node4", name: "根本原因" });
  }, 12000);
  setTimeout(() => {
    thinkingProcessVisualizer.value.addNode("node4", { id: "node5", name: "影响因素" });
  }, 16000);
  setTimeout(() => {
    thinkingProcessVisualizer.value.addNode("node5", { id: "node6", name: "方案A" });
  }, 20000)
});
</script>

<style>
.thinking-process-container {
  width: 100%;
  height: 600px;
  background-color: #f8f9fa;
  border-radius: 15px;
  /* box-shadow: 0 15px 30px rgba(0, 0, 0, 0.25); */
  padding: 30px;
  position: relative;
}

.thinking-svg {
  width: 100%;
  height: 100%;
  padding: 20px;
}

.node circle {
  cursor: pointer;
  transition: fill 0.3s ease;
}

.node circle:hover {
  box-shadow: 0 0 6px rgba(0, 0, 0, 0.1);
  transform: box-shadow 0.3s ease;
}

.node text {
  font-size: 14px;
  font-weight: 600;
}

.link {
  fill: none;
  stroke: #555;
  stroke-width: 2px;
  transition: stroke 0.3s ease;
}
@keyframes blink {
  0%, 100% { 
    opacity: 1; 
    transform: scale(1);
  }
  50% { 
    opacity: 0.7; 
    transform: scale(1.05);
  }
}

.blink {
  animation: blink 1s infinite;
}
</style>